#include "ultrasonic.h"
#include "delay.h"


void UltraSonic_Init(void)
{
    GPIO_InitTypeDef  GPIO_InitStructure;
    TIM_TimeBaseInitTypeDef  	TIM_TimeBaseInitStruct;

    // UlatrSonic-->PG14,PG15
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOG, ENABLE);	 //使能PG端口时钟
        
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_14;               // Trig
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; 		 //推挽输出
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;		 //IO口速度为50MHz
    GPIO_Init(GPIOG, &GPIO_InitStructure);					 //根据设定参数初始化

    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_15;	    		 // Echo
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU;            //设置成上拉输入
    GPIO_Init(GPIOG, &GPIO_InitStructure);	  				 //推挽输出 ，IO口速度为50MHz



    // 设置一个定时器，1us计数1个数，不用中断，且开始时不使能定时器
    //1、能定时器时钟。
    RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4,ENABLE);

    TIM_TimeBaseInitStruct.TIM_Prescaler	= 84-1;	            //84MHZ/8400 = 10000HZ  Prescaler范围1~65536 
    TIM_TimeBaseInitStruct.TIM_Period		= 50000-1;		    //在10000HZ时钟频率下，用时1ms 自动重装载寄存器值
    TIM_TimeBaseInitStruct.TIM_CounterMode	= TIM_CounterMode_Up;//向上计数
    TIM_TimeBaseInitStruct.TIM_ClockDivision= TIM_CKD_DIV1;  	 //分频因子
    //2、初始化定时器
    TIM_TimeBaseInit(TIM4,&TIM_TimeBaseInitStruct);

    //【不使能定时器】
    TIM_Cmd(TIM4, DISABLE);
}


float UltraSonic_GetDistance()
{
    float distance_cm = 0;
    u32 time_us = 0;
    //**************************************
    //启动超声波模块 也就是要发送启动信号
    GPIO_ResetBits(GPIOG, GPIO_Pin_14);
    delay_us(5);

    //高电平需要10us以上---【启动信号】
    GPIO_SetBits(GPIOG, GPIO_Pin_14);
    delay_us(15);
    GPIO_ResetBits(GPIOG, GPIO_Pin_14);
    
    //*********************************
    //设置定时器的CNT值为0，设置初值
    TIM_SetCounter(TIM4,0);

    //等待ECHO的高电平到来
    while(GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_15)==Bit_RESET);

    //**************************
    //【高电平来了】-------启动定时器
    TIM_Cmd(TIM4,ENABLE);
    
    //等待ECHO的低电平到来
    while(GPIO_ReadInputDataBit(GPIOG, GPIO_Pin_15)==Bit_SET);

    //****************************
    //【低电平来了】------读时间数据，关定时器
    //取出CNT的值-----定时器的当前值
    time_us = TIM_GetCounter(TIM4);    // 微秒 (μs)。
    //关闭定时器
    TIM_Cmd(TIM4, DISABLE);
    
    //**************************************
    //【通过公式】： 
    // distance (m) * 2 = time * 10(-6) * 340m/s
    // distance (m)     = time * 10(-6) * 340m/s / 2
    // distance (cm)    = time * 10(-6) * 340m/s / 2 * 100 = time * 10(-3) * 17
    distance_cm = time_us * 0.017;   // distance = time / 58;

    return distance_cm;
}